package com.ysu.zyw.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

/**
 * DateUtil provide an set of operation to Date.
 * <p>
 * Created by ZeRur on 2016/1/17.
 *
 * @author yaowu.zhang
 */
public class DateUtil {

    private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);

    /**
     * transform date to date str.
     *
     * @param date date to be formatted
     * @return date str with format yyyy-MM-dd HH:mm:ss
     */
    public static String format(Date date) {
        Assert.notNull(date, "null date is not allowed");
        return format(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * transform date to date str by given format.
     *
     * @param date   date to be formatted
     * @param format format
     * @return date str with format
     */
    public static String format(Date date, String format) {
        Assert.notNull(date, "null date is not allowed");
        Assert.notNull(format, "null format is not allowed");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        return simpleDateFormat.format(date);
    }

    /**
     * transform date str to date.
     *
     * @param dateStr date str
     * @return date
     */
    public static Date format(String dateStr) {
        Assert.hasText(dateStr, "empty date str is not allowed");
        return format(dateStr, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * transform date str to date.
     *
     * @param dateStr date str
     * @param format  format
     * @return date
     */
    public static Date format(String dateStr, String format) {
        Assert.hasText(dateStr, "empty date str is not allowed");
        Assert.hasText(format, "empty format is not allowed");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = simpleDateFormat.parse(dateStr);
        } catch (ParseException e) {
            logger.error("DateUtils - format - ", e);
        }
        return date;
    }

    /**
     * get the date object represent for the given time. all param is needed.
     *
     * @param year   year
     * @param month  month
     * @param date   date
     * @param hour   hour
     * @param minute minute
     * @param second second
     * @return date
     */
    public static Date getDate(int year, int month, int date, int hour, int minute, int second) {
        Calendar calendar = Calendar.getInstance();
        //noinspection MagicConstant
        calendar.set(year, month - 1, date, hour, minute, second);
        return calendar.getTime();
    }

    /**
     * add time to the given time.
     *
     * @param _date  given time
     * @param year   year
     * @param month  month
     * @param date   date
     * @param hour   hour
     * @param minute minute
     * @param second second
     * @return date
     */
    public static Date addTime(Date _date, int year, int month, int date, int hour, int minute, int second) {
        Assert.notNull(_date, "null date is not allowed");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(_date);
        calendar.add(Calendar.YEAR, year);
        calendar.add(Calendar.MONTH, month);
        calendar.add(Calendar.DATE, date);
        calendar.add(Calendar.HOUR_OF_DAY, hour);
        calendar.add(Calendar.MINUTE, minute);
        calendar.add(Calendar.SECOND, second);
        return calendar.getTime();
    }

    /**
     * set time to the given time, except date, other all can be null or an negative value.
     *
     * @param _date  given time
     * @param year   year
     * @param month  month
     * @param date   date
     * @param hour   hour
     * @param minute minute
     * @param second second
     * @return date
     */
    public static Date setTime(Date _date, Integer year, Integer month, Integer date, Integer hour, Integer minute,
                               Integer second) {
        Assert.notNull(_date, "null date is not allowed");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(_date);
        if (year != null)
            calendar.set(Calendar.YEAR, year);
        if (month != null)
            calendar.set(Calendar.MONTH, month);
        if (date != null)
            calendar.set(Calendar.DATE, date);
        if (hour != null)
            calendar.set(Calendar.HOUR_OF_DAY, hour);
        if (minute != null)
            calendar.set(Calendar.MINUTE, minute);
        if (second != null)
            calendar.set(Calendar.SECOND, second);
        return calendar.getTime();
    }

    /**
     * get all field of a date.
     *
     * @param date given date
     * @return a array stand for year / month / date / hour / minute / second.
     */
    public static int[] getTime(Date date) {
        Assert.notNull(date, "null date is not allowed");
        int[] times = new int[6];
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        times[0] = calendar.get(Calendar.YEAR);
        times[1] = calendar.get(Calendar.MONTH);
        times[2] = calendar.get(Calendar.DATE);
        times[3] = calendar.get(Calendar.HOUR_OF_DAY);
        times[4] = calendar.get(Calendar.MINUTE);
        times[5] = calendar.get(Calendar.SECOND);
        return times;
    }

}
